﻿using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Collections.Generic;

namespace JWBST.CommonClass
{
    public static class StringExtension
    {
        private static readonly Regex WebUrlExpression = new Regex(@"(http|https)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?", RegexOptions.Singleline | RegexOptions.Compiled);
        private static readonly Regex EmailExpression = new Regex(@"^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$", RegexOptions.Singleline | RegexOptions.Compiled);
        private static readonly Regex StripHTMLExpression = new Regex("<\\S[^><]*>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled);

        private static readonly char[] IllegalUrlCharacters = new[] { ';', '/', '\\', '?', ':', '@', '&', '=', '+', '$', ',', '<', '>', '#', '%', '.', '!', '*', '\'', '"', '(', ')', '[', ']', '{', '}', '|', '^', '`', '~', '–', '‘', '’', '“', '”', '»', '«' };

        [DebuggerStepThrough]
        public static bool IsWebUrl(this string target)
        {
            return !string.IsNullOrEmpty(target) && WebUrlExpression.IsMatch(target);
        }

        public static string FilteHtml(this string html)
        {
            if (!string.IsNullOrEmpty(html))
            {
                System.Text.RegularExpressions.Regex regex1 = new System.Text.RegularExpressions.Regex(@"<&#[^>]*;", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex2 = new System.Text.RegularExpressions.Regex(@" </?marquee[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex3 = new System.Text.RegularExpressions.Regex(@"</?object[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex4 = new System.Text.RegularExpressions.Regex(@"</?param[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex5 = new System.Text.RegularExpressions.Regex(@"</?embed[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex6 = new System.Text.RegularExpressions.Regex(@"</?table[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex7 = new System.Text.RegularExpressions.Regex(@"</?p[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex8 = new System.Text.RegularExpressions.Regex(@"</?a[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex9 = new System.Text.RegularExpressions.Regex(@"</?img[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex10 = new System.Text.RegularExpressions.Regex(@"</?span[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex11 = new System.Text.RegularExpressions.Regex(@"</?script[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex12 = new System.Text.RegularExpressions.Regex(@"</?font[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex13 = new System.Text.RegularExpressions.Regex(@"</?strong[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex14 = new System.Text.RegularExpressions.Regex(@"</?div[^>]*>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);


                html = regex1.Replace(html, ""); //过滤<script></script>标记
                html = regex2.Replace(html, ""); //过滤href=javascript: (<A>) 属性
                html = regex3.Replace(html, " _disibledevent="); //过滤其它控件的on...事件
                html = regex4.Replace(html, ""); //过滤iframe
                html = regex5.Replace(html, ""); //过滤frameset
                html = regex6.Replace(html, ""); //过滤frameset
                html = regex7.Replace(html, ""); //过滤frameset
                html = regex8.Replace(html, ""); //过滤frameset
                html = regex9.Replace(html, "");
                html = regex10.Replace(html, "");
                html = regex11.Replace(html, "");
                html = regex12.Replace(html, "");
                html = regex13.Replace(html, "");
                html = regex14.Replace(html, "");
                html = html.Replace("&nbsp;", "");
                html = html.Replace("<o:p>", "");
                html = html.Replace("</o:p>", "");
                html = html.Replace("<br>", "");
                html = html.Replace("<br />", "");
            }
            return html;
        }

        [DebuggerStepThrough]
        public static bool IsEmail(this string target)
        {
            return !string.IsNullOrEmpty(target) && EmailExpression.IsMatch(target);
        }

        [DebuggerStepThrough]
        public static string NullSafe(this string target)
        {
            return (target ?? string.Empty).Trim();
        }

        public static string SubStringAt(this string target, int length)
        {
            if (!string.IsNullOrEmpty(target))
            {

                string endStr = "...";
                string temp = target.Substring(0, (target.Length < length + 1) ? target.Length : length + 1);
                byte[] encodedBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(temp);

                string outputStr = "";
                int count = 0;

                for (int i = 0; i < temp.Length; i++)
                {
                    if ((int)encodedBytes[i] == 63)
                        count += 2;
                    else
                        count += 1;

                    if (count <= length - endStr.Length)
                        outputStr += temp.Substring(i, 1);
                    else if (count > length)
                        break;
                }

                if (count <= length)
                {
                    outputStr = temp;
                    endStr = "";
                }

                outputStr += endStr;

                return outputStr;
            }
            else
            {
                return target;
            }
        }

        [DebuggerStepThrough]
        public static string StripHtml(this string target)
        {
            return StripHTMLExpression.Replace(target, string.Empty);
        }

        [DebuggerStepThrough]
        public static Guid ToGuid(this string target)
        {
            Guid result = Guid.Empty;

            if ((!string.IsNullOrEmpty(target)) && (target.Trim().Length == 22))
            {
                string encoded = string.Concat(target.Trim().Replace("-", "+").Replace("_", "/"), "==");

                try
                {
                    byte[] base64 = Convert.FromBase64String(encoded);

                    result = new Guid(base64);
                }
                catch (FormatException)
                {
                }
            }

            return result;
        }

        [DebuggerStepThrough]
        public static T ToEnum<T>(this string target, T defaultValue) where T : IComparable, IFormattable
        {
            T convertedValue = defaultValue;

            if (!string.IsNullOrEmpty(target))
            {
                try
                {
                    convertedValue = (T)Enum.Parse(typeof(T), target.Trim(), true);
                }
                catch (ArgumentException)
                {
                }
            }

            return convertedValue;
        }


        [DebuggerStepThrough]
        public static string UrlEncode(this string target)
        {
            return HttpUtility.UrlEncode(target);
        }

        [DebuggerStepThrough]
        public static string UrlDecode(this string target)
        {
            return HttpUtility.UrlDecode(target);
        }

        [DebuggerStepThrough]
        public static string AttributeEncode(this string target)
        {
            return HttpUtility.HtmlAttributeEncode(target);
        }

        [DebuggerStepThrough]
        public static string HtmlEncode(this string target)
        {
            return HttpUtility.HtmlEncode(target);
        }

        [DebuggerStepThrough]
        public static string HtmlDecode(this string target)
        {
            return HttpUtility.HtmlDecode(target);
        }
        public static string FilteEnter(this string html)
        {
            if (!string.IsNullOrEmpty(html))
            {
                return html.Replace("\r\n", "<br />").Replace("\r", string.Empty).Replace("\n", string.Empty).Trim();
            }
            return html;
        }
        public static string FilteNull(this string html)
        {
            if (string.IsNullOrEmpty(html) || html.Trim().ToLower() == "null")
            {
                return "";
            }
            else
            {
                return html;
            }
        }
        public static string FilteNullReturnEmpty(this string html)
        {
            if (string.IsNullOrEmpty(html) || html.Trim().ToLower() == "null")
            {
                return "无";
            }
            else
            {
                return html.Replace(":00.0", ":00");
            }
        }
    }
}